// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rbchat.logic.chat_friend.gift;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.eva.android.AutoUpdateDaemon;
import com.eva.android.widget.DataLoadingAsyncTask;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.dto.DataFromServer;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.R;
import com.x52im.rbchat.network.http.HttpRestHelper;
import com.x52im.rainbowchat.http.logic.dto.GiftProcessResult;
import com.x52im.rainbowchat.http.logic.dto.RosterElementEntity;
import com.x52im.rbchat.logic.chat_friend.gift.model.GiftInPackageMeta;
import com.x52im.rbchat.logic.chat_friend.gift.model.GiftsMeta;

import java.util.Observer;

/**
 * 礼品相关数据的单例提供者类.
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @since 2.5
 */
public class GiftsProvider
{
	private final static String TAG = GiftsProvider.class.getSimpleName();
	
	private static GiftsProvider instance = null;
	
	/** 礼品基础数据缓存 */
	private GiftsMeta giftsMeta = null;
	/** 我的背包缓存数据 */
	private GiftInPackageMeta giftInPackageMeta = null;
	
	/** 本地用户的当前积分 */
	private int currentScore = 0;
	
	public static GiftsProvider getIntance()
	{
		if(instance == null)
			instance = new GiftsProvider();
		
		return instance;
	}
	
	public GiftsProvider()
	{
		giftsMeta = new GiftsMeta();
		giftInPackageMeta = new GiftInPackageMeta();
	}
	
	/**
	 * 返回礼品的基础数据.
	 * <p>
	 * 重要说明：当礼品基础数据尚未载入时，返回的对象里肯定是空数据的。
	 * 那么此时应该尝试加载之，推荐使用{@link GiftsProvider.LoadGiftsMetaAsyncTask}
	 * 无条件尝试加载数据以保证无论何种情况下使用时一定是加载好的数据.
	 * 
	 * @param loadDataIfNo
	 * @return
	 * @see GiftsProvider.LoadGiftsMetaAsyncTask
	 */
	public GiftsMeta getGiftsMeta(boolean loadDataIfNo)
	{
		if(loadDataIfNo && giftsMeta != null && !giftsMeta.isHasLoaded())
			giftsMeta.loadDatas();
		return giftsMeta;
	}
	
	/**
	 * 返回我的礼品包数据.
	 * <p>
	 * 重要说明：当我的礼品包数据尚未载入时，返回的对象里肯定是空数据的。
	 * 那么此时应该尝试加载之，推荐使用{@link GiftsProvider.LoadGiftInPackageMetaAsyncTask}
	 * 无条件尝试加载数据以保证无论何种情况下使用时一定是加载好的数据.
	 * 
	 * @param loadDataIfNo
	 * @return
	 * @see GiftsProvider.LoadGiftInPackageMetaAsyncTask
	 */
	public GiftInPackageMeta getGiftInPackageMeta(boolean loadDataIfNo, Context context)
	{
		if(loadDataIfNo && giftInPackageMeta != null && !giftInPackageMeta.isHasLoaded())
			giftInPackageMeta.loadDatas(context);
		return giftInPackageMeta;
	}
	
	public void setCurrentScore(int currentScore)
	{
		this.currentScore = currentScore;
	}
	public int getCurrentScore()
	{
		return currentScore;
	}
	
	//----------------------------------------------------------------------------------------- inner classes
	/**
	 * 礼品包数据载入异步实现类.
	 */
	public static class LoadGiftInPackageMetaAsyncTask extends DataLoadingAsyncTask<Object, Integer, GiftInPackageMeta>
	{
		private Context parentActivity = null;
		private Observer obsAfterLoadSucess = null;
		
		public LoadGiftInPackageMetaAsyncTask(Context parentActivity)
		{
			super(parentActivity, false);//, parentActivity.getString(R.string.general_loading));
			this.parentActivity = parentActivity;
		}

		/**
		 * 在后台执行 .
		 * 
		 * @param params 外界传进来的参数
		 * @return 查询结果，将传递给onPostExecute(..)方法
		 */
		@Override
		protected GiftInPackageMeta doInBackground(Object... params) 
		{
			if(params != null && params.length == 2)
			{
				GiftInPackageMeta senceMeta = (GiftInPackageMeta)params[0];
				obsAfterLoadSucess = (Observer)params[1];
				
				//** 如果该场景数据沿未载入则载入之
				if(!senceMeta.isHasLoaded())
					senceMeta.loadDatas(parentActivity);
				
				return senceMeta;
			}
			return null;
		}

		/**
		 * 处理服务端返回的登陆结果信息.
		 * 
		 * @see AutoUpdateDaemon
		 */
		protected void onPostExecuteImpl(Object result)
		{
			GiftInPackageMeta senceMeta = (GiftInPackageMeta)result;
			
			if(obsAfterLoadSucess != null)
				obsAfterLoadSucess.update(null, senceMeta);
		}
	}
	
	/**
	 * 礼品基础数据载入异步实现类.
	 */
	public static class LoadGiftsMetaAsyncTask extends DataLoadingAsyncTask<Object, Integer, GiftsMeta>
	{
		private Context parentActivity = null;
		private Observer obsAfterLoadSucess = null;
		
		public LoadGiftsMetaAsyncTask(Context parentActivity)
		{
			super(parentActivity, false);//, parentActivity.getString(R.string.general_loading));
			this.parentActivity = parentActivity;
		}

		/**
		 * 在后台执行 .
		 * 
		 * @param params 外界传进来的参数
		 * @return 查询结果，将传递给onPostExecute(..)方法
		 */
		@Override
		protected GiftsMeta doInBackground(Object... params) 
		{
			if(params != null && params.length == 2)
			{
				GiftsMeta senceMeta = (GiftsMeta)params[0];
				obsAfterLoadSucess = (Observer)params[1];
				
				//** 如果该场景数据沿未载入则载入之
				if(!senceMeta.isHasLoaded())
					senceMeta.loadDatas();
				
				return senceMeta;
			}
			return null;
		}

		/**
		 * 处理服务端返回的登陆结果信息.
		 * 
		 * @see AutoUpdateDaemon
		 */
		protected void onPostExecuteImpl(Object result)
		{
			GiftsMeta senceMeta = (GiftsMeta)result;
			
			if(obsAfterLoadSucess != null)
				obsAfterLoadSucess.update(null, senceMeta);
		}
	}
	
	/**
	 * 用户积分查询异步实现类（积分查询逻辑放到服务端的原因是出于安全考虑）.
	 */
	public static class QueryScoreAsyncTask extends DataLoadingAsyncTask<Object, Integer, DataFromServer>
	{
		private Context parentActivity = null;
		private Observer obsAfterLoadSucess = null;
		
		public QueryScoreAsyncTask(Context parentActivity, Observer obsAfterLoadSucess)
		{
			super(parentActivity, false);//parentActivity.getString(R.string.general_loading));
			this.parentActivity = parentActivity;
			this.obsAfterLoadSucess = obsAfterLoadSucess;
		}

		/**
		 * 在后台执行 .
		 * 
		 * @param params 外界传进来的参数
		 * @return 查询结果，将传递给onPostExecute(..)方法
		 */
		@Override
		protected DataFromServer doInBackground(Object... params) 
		{
			RosterElementEntity localRee = MyApplication.getInstance(parentActivity)
					.getIMClientManager().getLocalUserInfo();
			if(localRee != null)
//				return HttpServiceFactory4AImpl.getInstance().getDefaultService().sendObjToServer(
//					DataFromClient.n().setProcessorId(MyProcessorConst.PROCESSOR_GIFT)
//					.setJobDispatchId(JobDispatchConst.LOGIC_GIFTANDSCORE)
//					.setActionId(SysActionConst.ACTION_APPEND1)
//					.setNewData(localRee.getUser_uid()));
				return HttpRestHelper.queryUserScoreFromServer(localRee.getUser_uid());
			else
				return new DataFromServer().setSuccess(false);
		}

		/**
		 * 处理服务端返回的登陆结果信息.
		 * 
		 * @see AutoUpdateDaemon
		 */
		protected void onPostExecuteImpl(Object result)
		{
			String scoreStr = (String)result;
			int score = CommonUtils.getIntValue(scoreStr);
			
			if(obsAfterLoadSucess != null)
				obsAfterLoadSucess.update(null, score);
		}
	}
	
	/**
	 * 提交礼品赠送相关数据处理的异步加载类(注意：本类
	 * 目前执行于非ui线程中的TransDataListener，不要涉及任何UI作，否则程序将崩溃！).
	 */
	public static class SubmitSendGiftAsyncTask extends AsyncTask<Object, Integer, DataFromServer>
	{
		private Context parentActivity = null;
//		private Observer obsAfterLoadSucess = null;
		private String srcUid = null;
		private String destUid = null;
		private String giftIdent = null;
		
		public SubmitSendGiftAsyncTask(Context parentActivity
				, String srcUid, String destUid, String giftIdent
//				, Observer obsAfterLoadSucess
				)
		{
			this.parentActivity = parentActivity;
			this.srcUid = srcUid;
			this.destUid = destUid;
			this.giftIdent = giftIdent;
//			this.obsAfterLoadSucess = obsAfterLoadSucess;
		}

		/**
		 * 在后台执行 .
		 * 
		 * @param params 外界传进来的参数
		 * @return 查询结果，将传递给onPostExecute(..)方法
		 */
		@Override
		protected DataFromServer doInBackground(Object... params) 
		{
			RosterElementEntity localRee = MyApplication.getInstance(parentActivity)
					.getIMClientManager().getLocalUserInfo();
			if(localRee != null)
//				return HttpServiceFactory4AImpl.getInstance().getDefaultService().sendObjToServer(
//					DataFromClient.n().setProcessorId(MyProcessorConst.PROCESSOR_GIFT)
//					.setJobDispatchId(JobDispatchConst.LOGIC_GIFTANDSCORE)
//					.setActionId(SysActionConst.ACTION_APPEND2)
//					.setNewData(new String[]{srcUid, destUid, giftIdent}));
				return HttpRestHelper.submitSendGifToFriendFromServer(srcUid, destUid, giftIdent);
			else
				return new DataFromServer().setSuccess(false);
		}

		/**
		 * 处理服务端返回的登陆结果信息.
		 * 
		 * @see AutoUpdateDaemon
		 */
		protected void onPostExecute(DataFromServer result)
		{
			if(result != null && result.isSuccess())
			{
//				String retFlag = (String)result.getReturnValue();
//				if(!(result.getReturnValue() instanceof GiftProcessResult))
				if(result.getReturnValue() == null)
				{
					Log.w(TAG, "result.getReturnValue()是空的，不是合法的返回数据！");
					return;
				}
				
//				GiftProcessResult gpr = (GiftProcessResult)result.getReturnValue();
				GiftProcessResult gpr = HttpRestHelper.parseSendGifToFriendFromServer(
						(String)result.getReturnValue());
				
				// 服务端处理成功完成
				if(gpr.getResultCode() == GiftProcessResult.RESULT_CODE_OK)
				{
					onPostExecute_sucess(CommonUtils.getIntValue(gpr.getResultValue()));
//					if(obsAfterLoadSucess != null)
//						obsAfterLoadSucess.update(null, null);
				}
				else if(gpr.getResultCode() == GiftProcessResult.RESULT_CODE_NO$PRICE)
					Log.e(TAG, "收到用户"+srcUid+"发过来的礼品"+giftIdent
							+", 但服务端在更新相关数据时出错了，gpr.getResultCode()="+gpr.getResultCode());
				// 积分不足
				else if(gpr.getResultCode() == GiftProcessResult.RESULT_CODE_SCORE$NOT$ENOUGTH)
				{
					onPostExecute_scoreNotEnough(CommonUtils.getIntValue(gpr.getResultValue()));
//					Log.e(TAG, "收到用户"+srcUid+"发过来的礼品"+giftIdent+", 但服务端在更新相关数据时出错了，返回码="+retFlag);
				}
				// 其它错误
				else if(gpr.getResultCode() == GiftProcessResult.RESULT_CODE_OTHERERROR)
				{
					onPostExecute_otherError(CommonUtils.getIntValue(gpr.getResultValue()));
				}
				else
					Log.e(TAG, "收到用户"+srcUid+"发过来的礼品"+giftIdent
							+", 但服务端在更新相关数据时出错了，gpr.getResultCode()="+gpr.getResultCode());
			}
		}
		
		/**
		 * 成功处理后要调用的方法.
		 * 
		 * @param _currentScore Integer对象，本地用户的当前总积分数
		 */
		protected void onPostExecute_sucess(int _currentScore)
		{
			// default do nothing
		}
		
		/**
		 * 积分不足时要调用的方法.
		 * 
		 * @param _currentScore Integer对象，本地用户的当前总积分数
		 */
		protected void onPostExecute_scoreNotEnough(int _currentScore)
		{
			// default do nothing
		}
		
		/**
		 * 服务端返回其它错误时要调用的方法.
		 * <p>
		 * 通常在此种情况下，客户端上层应用只要给用户提示礼品发送失败就可以了.
		 * 
		 * @param _currentScore Integer对象，本地用户的当前总积分数
		 */
		protected void onPostExecute_otherError(int _currentScore)
		{
			// default do nothing
		}
	}
	
	/**
	 * 礼品兑换异步线程.
	 */
	public static class GiftToJifenAsyncTask extends DataLoadingAsyncTask<Object, Integer, DataFromServer>
	{
		public GiftToJifenAsyncTask(Context parentActivity)
		{
			super(parentActivity, parentActivity.getString(R.string.chatting_gift_score_exchanging));
		}

		/**
		 * 在后台执行 .
		 * 
		 * @param params 外界传进来的参数
		 * @return 查询结果，将传递给onPostExecute(..)方法
		 */
		@Override
		protected DataFromServer doInBackground(Object... params) 
		{
			RosterElementEntity localRee = MyApplication.getInstance(context)
					.getIMClientManager().getLocalUserInfo();
			if(localRee != null)
				return HttpRestHelper.submitGiftToJifenFromServer(localRee.getUser_uid());
			else
				return new DataFromServer().setSuccess(false);
		}

		@Override
		protected void onPostExecuteImpl(Object result)
		{
			if(result == null)
			{
				Log.w(TAG, "result.getReturnValue()是空的，不是合法的返回数据！");
				return;
			}
			
			GiftProcessResult gpr = HttpRestHelper.parseSendGifToFriendFromServer(
					(String)result);//(GiftProcessResult)result;
			
			try
			{
				// 服务端处理成功完成
				if(gpr.getResultCode() == GiftProcessResult.RESULT_CODE_OK)
					onPostExecute_sucess(CommonUtils.getIntValue(gpr.getResultValue()));
				// 其它错误
				else if(gpr.getResultCode() == GiftProcessResult.RESULT_CODE_OTHERERROR)
					onPostExecute_error(CommonUtils.getIntValue(gpr.getResultValue()));
				else
					Log.e(TAG, "服务端在礼品转积分时出错了，gpr.getResultCode()="+gpr.getResultCode());
			}
			catch (Exception e)
			{
				Log.e(GiftsProvider.class.getSimpleName(), e.getMessage(), e);
			}
		}	
		
		/**
		 * 成功处理后要调用的方法.
		 * 
		 * @param _currentScore Integer对象，本地用户的当前总积分数
		 */
		protected void onPostExecute_sucess(int _currentScore)
		{
			// default do nothing
		}
		
		/**
		 * 服务端返回其它错误时要调用的方法.
		 * 
		 * @param _currentScore Integer对象，本地用户的当前总积分数
		 */
		protected void onPostExecute_error(int _currentScore)
		{
			// default do nothing
		}
	}
}
